package cn.kgc.service.impl;

import cn.kgc.constants.Constants;
import cn.kgc.dto.UsersDto;
import cn.kgc.mapper.UsersMapper;
import cn.kgc.pojo.Users;
import cn.kgc.service.UsersService;
import cn.kgc.utils.UUIDUtils;
import cn.kgc.utils.UrlUtils;
import cn.kgc.utils.redis.RedisKeyUtils;
import cn.kgc.utils.redis.RedisUtils;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;


/**
 * <p>
 * 用户 服务实现类
 * </p>
 *
 * @author qf
 * @since 2022-03-03
 */
@Service
public class UsersServiceImpl extends ServiceImpl<UsersMapper, Users> implements UsersService {

    private final UsersMapper usersMapper;

    private final RedisUtils redisUtils;

    public UsersServiceImpl(UsersMapper usersMapper, RedisUtils redisUtils) {
        this.usersMapper = usersMapper;
        this.redisUtils = redisUtils;
    }

    @Override
    public UsersDto loginByWechat(String access_token, String openid) throws UnsupportedEncodingException {
        UsersDto ud = null;
        // 1.判断openid是不是在数据库中存在
        ud = usersMapper.getUserDtoByOpenid(openid);
        // 等于null 表示没有查到，第一次扫描，获取用户信息
        if (null == ud) {
            String infoUrl = "https://api.weixin.qq.com/sns/userinfo?" +
                    "access_token=" + access_token +
                    "&openid=" + openid +
                    "&lang=zh_CN";
            // 从微信获取数据
            String infoJson = UrlUtils.loadURL(infoUrl);
            // 解析成map对象 因为名字不一样
            HashMap<String, Object> infoMap = JSON.parseObject(infoJson, HashMap.class);
            // 获取map中的属性，保存到userss对象中
            Users users = new Users();

            users.setUserName(URLEncoder.encode (infoMap.get("nickname").toString(),"UTF-8"));

            users.setFaceUrl(infoMap.get("headimgurl").toString());
            users.setOpenId(openid);
            // users存到数据库中
            usersMapper.insert(users);
            ud = new UsersDto(users);
        }

        // 无论是不是第一次登录，都需要存到redis中，并且返回给用户
        setToken(ud);
        return ud;
    }

    @Override
    public Map<String, Object> getInfo(String token) {
        Map<String,Object> map=null;
        String key=RedisKeyUtils.formatKeyWithPrefix (Constants.Redis.PREFIX_TOKEN,token);
        String valueJson=redisUtils.getValue (key);
        map=JSON.parseObject (valueJson,HashMap.class);
        return map;
    }

    public String loginSms(String phone,String sms){
        String token="";
        QueryWrapper<Users> wrapper = new QueryWrapper<> ();
        wrapper.eq ("account",phone);
        Users users = usersMapper.selectOne (wrapper);
        if(users==null){
            users = new Users ();
            users.setUserName (phone);
            users.setAccount (phone);
            usersMapper.insert (users);
        }

        String key=RedisKeyUtils.formatKeyWithPrefix (Constants.Redis.PREFIX_SMS,Constants.Sms.TYPE_REGIST_OR_LOGIN.toString (),phone);
        String redisSms = redisUtils.getValue (key);
        if(!StringUtils.isBlank (redisSms) && redisSms.equals (sms)){
            UsersDto usersDto = new UsersDto (users);
            setToken (usersDto);
            token=usersDto.getToken ();
        }
        return token;
    }


    // 存入redis
    private void setToken(UsersDto usersDto) {

        // 1.token的key
        String uuid32 = UUIDUtils.getUUID32();
        // 将生成uuid给usersDto
        usersDto.setToken(uuid32);
        // 2.拼接之后的前缀，有目录结构
        String key = RedisKeyUtils.formatKeyWithPrefix(Constants.Redis.PREFIX_TOKEN, uuid32);
        // 3.将usersDto对象转为json对象
        String usersJson = JSON.toJSONString(usersDto);
        // 第三个参数不写，就不设置时间，一般推荐设置时间
        redisUtils.putValue(key, usersJson, Constants.Duration.HALF_AN_HOUR);
    }

}

